<template>
  <div class="websocket-client">
    <h3>WebSocket 客户端</h3>
    
    <div class="connection-status">
      连接状态: 
      <span :class="isConnected ? 'connected' : 'disconnected'">
        {{ isConnected ? '已连接' : '未连接' }}
      </span>
    </div>

    <div class="message-controls">
      <input 
        type="text" 
        v-model="messageInput" 
        placeholder="输入消息..."
        :disabled="!isConnected"
      >
      <button 
        @click="sendMessage" 
        :disabled="!isConnected || !messageInput"
      >
        发送消息
      </button>
      <button 
        @click="isConnected ? closeConnection() : connect()"
      >
        {{ isConnected ? '断开连接' : '连接服务器' }}
      </button>
    </div>

    <div class="message-history">
      <h4>消息历史:</h4>
      <div v-for="(msg, index) in messageHistory" :key="index" class="message-item">
        <span :class="msg.isSent ? 'sent' : 'received'">
          {{ msg.isSent ? '我' : '服务器' }}: {{ msg.content }}
        </span>
        <span class="time">{{ msg.timestamp }}</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from 'vue';

// 定义消息类型接口
interface WebSocketMessage {
  content: string;
  isSent: boolean;
  timestamp: string;
}

// WebSocket配置
const WS_URL = ref('ws://localhost:9011/ws'); // 后端WebSocket地址
const isConnected = ref(false);
const webSocket = ref<WebSocket | null>(null);
const messageInput = ref('');
const messageHistory = ref<WebSocketMessage[]>([]);

// 格式化时间
const formatTime = () => {
  const date = new Date();
  return date.toLocaleTimeString();
};

// 连接WebSocket
const connect = () => {
  if (isConnected.value) return;

  try {
    webSocket.value = new WebSocket(WS_URL.value);
    
    // 连接成功
    webSocket.value.onopen = () => {
      console.log('WebSocket连接成功');
      isConnected.value = true;
      addMessage('连接服务器成功', false);
    };

    // 接收消息
    webSocket.value.onmessage = (event) => {
      console.log('收到消息:', event.data);
      addMessage(event.data, false);
    };

    // 连接关闭
    webSocket.value.onclose = (event) => {
      console.log(`WebSocket关闭: ${event.code} ${event.reason}`);
      isConnected.value = false;
      addMessage(`连接已关闭: ${event.reason}`, false);
      webSocket.value = null;
    };

    // 连接错误
    webSocket.value.onerror = (error) => {
      console.error('WebSocket错误:', error);
      addMessage('连接发生错误', false);
    };
  } catch (error) {
    console.error('连接失败:', error);
    addMessage('连接服务器失败', false);
  }
};

// 关闭连接
const closeConnection = () => {
  if (webSocket.value && isConnected.value) {
    webSocket.value.close(1000, '正常关闭');
  }
};

// 发送消息
const sendMessage = () => {
  if (!webSocket.value || !isConnected.value || !messageInput.value.trim()) return;

  const message = messageInput.value.trim();
  try {
    webSocket.value.send(message);
    addMessage(message, true);
    messageInput.value = ''; // 清空输入框
  } catch (error) {
    console.error('发送消息失败:', error);
    addMessage('发送消息失败', false);
  }
};

// 添加消息到历史记录
const addMessage = (content: string, isSent: boolean) => {
  messageHistory.value.push({
    content,
    isSent,
    timestamp: formatTime()
  });
  
  // 保持滚动到底部
  setTimeout(() => {
    const container = document.querySelector('.message-history');
    if (container) {
      container.scrollTop = container.scrollHeight;
    }
  }, 0);
};

// 组件挂载时连接
onMounted(() => {
  connect();
});

// 组件卸载时关闭连接
onUnmounted(() => {
  closeConnection();
});

// 监听窗口关闭事件
watch(isConnected, (newVal) => {
  if (newVal) {
    window.addEventListener('beforeunload', closeConnection);
  } else {
    window.removeEventListener('beforeunload', closeConnection);
  }
}, { immediate: true });
</script>

<style scoped>
.websocket-client {
  max-width: 800px;
  margin: 20px auto;
  padding: 20px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.connection-status {
  margin: 15px 0;
  padding: 10px;
  border-radius: 4px;
  background-color: #f5f5f5;
}

.connected {
  color: #4caf50;
  font-weight: bold;
}

.disconnected {
  color: #f44336;
  font-weight: bold;
}

.message-controls {
  display: flex;
  gap: 10px;
  margin: 20px 0;
}

.message-controls input {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}

.message-controls button {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  background-color: #2196f3;
  color: white;
  cursor: pointer;
  transition: background-color 0.3s;
}

.message-controls button:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.message-controls button:not(:disabled):hover {
  background-color: #0b7dda;
}

.message-history {
  margin-top: 20px;
  padding: 15px;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  max-height: 400px;
  overflow-y: auto;
}

.message-item {
  margin: 8px 0;
  padding: 8px 12px;
  border-radius: 4px;
  max-width: 70%;
}

.sent {
  background-color: #e3f2fd;
  float: right;
}

.received {
  background-color: #f1f8e9;
  float: left;
}

.time {
  display: block;
  font-size: 12px;
  color: #757575;
  margin-top: 4px;
}

.message-item::after {
  content: "";
  clear: both;
  display: table;
}
</style>
